package com.ljx.funchat.chat.consume;

import cn.hutool.core.util.StrUtil;
import com.ljx.funchat.chat.dao.ContactDao;
import com.ljx.funchat.chat.dao.MessageDao;
import com.ljx.funchat.chat.dao.RoomDao;
import com.ljx.funchat.chat.dao.RoomFriendDao;
import com.ljx.funchat.chat.domain.entity.*;
import com.ljx.funchat.chat.domain.enums.RoomTypeEnum;
import com.ljx.funchat.chat.domain.vo.resp.ChatMessageResp;
import com.ljx.funchat.chat.service.ChatService;
import com.ljx.funchat.chat.service.cache.GroupMemberCache;
import com.ljx.funchat.chat.service.cache.RoomCache;
import com.ljx.funchat.common.constant.RedisKey;
import com.ljx.funchat.common.utils.RedisUtils;
import com.ljx.funchat.transaction.config.RabbitMQConfig;
import com.ljx.funchat.transaction.domain.dto.MsgSendMessageDTO;
import com.ljx.funchat.user.service.impl.PushService;
import com.ljx.funchat.websocket.domain.vo.resp.WSMessage;
import com.ljx.funchat.websocket.service.WebSocketService;
import com.ljx.funchat.websocket.service.adatper.WebSocketAdapter;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static com.ljx.funchat.common.constant.RedisKey.MSG_CONSUME_AGAIN_EXPIRE;

/**
 * 发送消息消费者
 */
@Component
@RabbitListener(queues = {RabbitMQConfig.MSG_QUEUE})
public class MsgSendConsumer {

    @Autowired
    private MessageDao messageDao;

    @Autowired
    private RoomCache roomCache;

    @Autowired
    private RoomDao roomDao;

    @Autowired
    private GroupMemberCache groupMemberCache;

    @Autowired
    private RoomFriendDao roomFriendDao;

    @Autowired
    private ChatService chatService;

    @Autowired
    private ContactDao contactDao;

    @Autowired
    private PushService pushService;

    @RabbitHandler
    public void handleMessage(MsgSendMessageDTO messageDTO) {
        Message message = messageDao.getById(messageDTO.getMsgId());
        // 检查是否重复消费
        Boolean isConsume = isConsume(message.getId());
        if (isConsume){
            return;
        }
        Room room = roomCache.get(message.getRoomId());
        // 更新房间的最新消息和时间
        roomDao.refreshActiveTime(room.getId(), message.getId(), message.getCreateTime());
        // 删除缓存
        roomCache.delete(room.getId());
        // 获取群成员
        List<Long> memberList;
        if (room.getType().equals(RoomTypeEnum.GROUP.getType())){
            memberList = groupMemberCache.getMemberUidList(room.getId());
        } else {
            RoomFriend roomFriend = roomFriendDao.getByRoomId(room.getId());
            memberList = Arrays.asList(roomFriend.getUid1(), roomFriend.getUid2());
        }
        // 更新会话内容
        contactDao.refreshMsg(room.getId(), memberList, message.getId(), message.getCreateTime());
        // 给聊天成员推送消息
        ChatMessageResp wsMessage = chatService.getMsgResp(message, null, messageDTO.getUid());
        pushService.sendPushMsg(RabbitMQConfig.PUSH_QUEUE, WebSocketAdapter.buildMsgSend(wsMessage), memberList);
        // 防止重复消费
        RedisUtils.set(RedisKey.getKey(RedisKey.MSG_CONSUME_AGAIN, message.getId()), "1", MSG_CONSUME_AGAIN_EXPIRE, TimeUnit.DAYS);
    }

    /**
     * 检验是否重复消费
     * @param msgId
     * @return
     */
    private Boolean isConsume(Long msgId) {
        String str = RedisUtils.getStr(RedisKey.getKey(RedisKey.MSG_CONSUME_AGAIN, msgId));
        return StrUtil.isNotBlank(str);
    }

}
